using System;
using System.IO;
using System.Text;
using System.Diagnostics;

using A4G.Core;
using Mapack;

namespace A4G.Assignment3
{
	public class Program
	{
		static void PrintHelp()
		{
			Console.WriteLine("Algorithm For Genomes Assignment 3.");
			Console.WriteLine("Start as follows:");
			Console.WriteLine("a4g.assignment3 <filename1>");
			Console.WriteLine("Where <filename1> is the fasta files containing the DNA sequence.");
		}

		static void Main(string[] args)
		{
			if (args.Length != 1)
			{
				throw new ApplicationException("Insufficient program arguments");
			}

			string filename1 = args[0];
			if (!File.Exists(filename1))
			{
				Console.WriteLine("Filename incorrect.");
				Console.WriteLine();
				PrintHelp();
				return;
			}

			FastaFile inputFile1 = new FastaFile(filename1);
			inputFile1.Load();

			char[] observations = new char[] {'A', 'C', 'G', 'T'};
			char[] states = new char[] {'N', 'I'};

			Matrix A = new Matrix(2,2,0);
			A[0, 0] = 0.75;
			A[0, 1] = 0.25;
			A[1, 0] = 0.40;
			A[1, 1] = 0.60;

			Matrix E = new Matrix(2,4,0);
			E[1, 0] = 0.069409179; // 0.405071967;			// 0.591;
			E[1, 1] = 0.156904675; // 0.915695682;			// 1.336;
			E[1, 2] = 0.17135024; // 0.9999;				// 1.459;
			E[1, 3] = 0.072227826; // 0.42152159;			// 0.615;
			E[0, 0] = 0.122963469; // 0.717614805;			// 1.047;
			E[0, 1] = 0.116034295; // 0.677176148;			// 0.988;
			E[0, 2] = 0.111923769; // 0.653187114;			// 0.953;
			E[0, 3] = 0.118852942; // 0.693625771;			// 1.012;

			double[] initialProbs = new double[] { 0.95, 0.05};

			Viterbi v = new Viterbi();
			char[] statePath = v.CalculateMostProbableStatePath(
				((Sequence)inputFile1.Sequences[0]).SequenceString.ToCharArray(),
				observations,
				states,
				A,
				E,
				initialProbs);
				
			StreamWriter writer = new StreamWriter(Path.ChangeExtension(filename1, "a4g.output"));
			try
			{
				foreach (char state in statePath)
				{
					writer.Write(state);
					Debug.Write(state);
				}
				Debug.WriteLine("");
			}
			finally
			{
				writer.Close();
			}
		}
	}
}
